<?php

namespace App\Http\Controllers\Wf\Common;

use DB;
use Response;
use Carbon\Carbon;
use Ramsey\Uuid\Uuid;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;
use App\Eloqumd\Wf\WfMenu;
use App\Eloqumd\Wf\WfCompany;
use App\Eloqumd\Wf\WfRole;
use App\Eloqumd\Wf\WfUser;
use Jishulin\WorkFlowEngine\Tools\Tools;

class Share
{
    private	static $_instance;

    public static function getInstance()
    {
        if (! (self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    public function initQNBucket($init = 'up', $key = '')
    {
        $accessKey = '6-vR074y9LIQ733kgycjSN_kX75l0MxTFLE9myWJ';
        $secretKey = 'jvD9W5Bn0C-lUgaqZxgTgUyrq9kSVmP_6CWNGTwX';
        $bucket = 'jishulin';
        $qnurl = 'http://qb4yo9ydu.bkt.clouddn.com/';
        $auth = new Auth($accessKey, $secretKey);
        if ($init == 'up') {
            $key = empty($key) ? (Carbon::now()->toW3cString() . '-' .  session_create_id()) : $key;
            $token = $auth->uploadToken($bucket);
            $uploadMgr = new UploadManager();

            return [$uploadMgr, $token, $key];
        } elseif ($init == 'vf') {
            $config = new \Qiniu\Config();
            $bucketManager = new BucketManager($auth, $config);

            return list($fileInfo, $err) = $bucketManager->stat($bucket, $key);
        } elseif ($init == 'vv') {
            return $qnurl . urlencode($key);
        }
    }

    public function initQTCucket($init = 'up', $key = '')
    {
        $secretId = "AKID71g6HCnZOxKTLx8VWJtEKBoFTYNBm8F6";
        $secretKey = "pQnvztXxi16EHE7vXwkgNo31vgHdmiPt";
        $region = "ap-nanjing";
        $bucket = "jishulin-1258682100";
        $cosClient = new \Qcloud\Cos\Client(
            array(
                'region' => $region,
                'schema' => 'http',
                'credentials'=> array(
                    'secretId'  => $secretId ,
                    'secretKey' => $secretKey
                )
            )
        );

        if ($init == 'up') {
            $key = empty($key) ? (Carbon::now()->toW3cString() . '-' .  session_create_id()) : $key;
            return [$cosClient, $bucket, $key];
        } elseif ($init == 'vv') {
            return $signedUrl = $cosClient->getObjectUrl($bucket, $key, '+60 minutes');
        }
    }

    public function getSrcByKey($key)
    {
        return $this->initQTCucket('vv', $key);
    }

    public function imageUpload(Request $request)
    {
        if (false === $file = $this->checkFile($request)) {
            return Response::json(['code' => 50000, 'message' => trans('wf.Upload-Error')]);
        }
        $fileExtension = strtolower($file->getClientOriginalExtension());
        $filePath = $file->getRealPath();
        $files = fopen($filePath, "rb");
        list($cosClient, $bucket, $key) = $this->initQTCucket();

        $uploadKey = $key . '.' .$fileExtension;

        try {
            $result = $cosClient->putObject(array(
                'Bucket' => $bucket,
                'Key' => $uploadKey,
                'Body' => $files
            ));
            // print_r($result);

            $finalKey = $result['Key'];

            $signedUrl = $cosClient->getObjectUrl($bucket, $finalKey, '+60 minutes');

            return Response::json(['code' => 10000, 'message' => trans('wf.Upload-Success'), 'data' => [
                'key' => $finalKey,
                'src' => $signedUrl
            ]]);
        } catch (\Exception $e) {
            return Response::json(['code' => 50000, 'message' => $e->getMessasge()]);
        }
    }

    public function checkFile($request)
    {
        $file = null;
        $tag = null;
        if ($request->hasFile('file')) {
            $file = $request->file('file');
        } elseif ($request->hasFile('images')) {
            $file = $request->file('images');
        } elseif ($request->hasFile('editormd-image-file')) {
            $file = $request->file('editormd-image-file');
            $tag = 'md';
        } elseif ($request->hasFile('image')) {
            $file = $request->file('image');
        } elseif ($request->hasFile('img')) {
            $file = $request->file('img');
        }

        // 不存在上传文件信息
        if (is_null($file)) {
            return false;
        }

        // 判断文件是否有效
        if (!$file->isValid()) {
            return false;
        }

        return $file;
    }

	/**
	 * 获取菜单 子菜单在在父菜单的sub中
	 * @name    getMenuSub
	 *
	 * @param   integer         $parent_id          上级菜单，默认为顶级菜单
	 * @param   array           $userInfo           用户信息
	 * @param   int             $tag                优化排除非菜单权限
	 *
	 * @return  array
	 */
	public static function getMenuSub($apiUser = [], $tag = 0)
	{
	    $where[] = ['status', '=', 1, 'AND'];

	    if ($tag) {
	        $where[] = ['type', '=', 'menu', 'AND'];
	    } else {
	        $where[] = ['type', '=', 'button', 'AND'];
	    }
	    // 系统级菜单权限过滤
	    if ($apiUser['user_type'] != 0) {
	        $where[] = ['show', '=', 1, 'AND'];
	    }

        $whereIn = [];
        if ($apiUser['user_type'] == 1) {
            $companyAuths = WfCompany::where('id', $apiUser['company_id'])->value('auth');
            empty($companyAuths) ? $where[] = ['id', '=', 0, 'AND'] : $whereIn = ['id', explode(',', $companyAuths)];
        } elseif ($apiUser['user_type'] == 2) {
            // 权限处理
            // 获取角色的权限
            $roles = WfRole::whereIn('id', explode(',', $apiUser['role']))->pluck('auth');
            $auths = [];
            foreach ($roles as $key => $val) {
                $auths = array_merge($auths, explode(',', $val));
            }
            $auths = array_unique($auths);

            $userAuth = WfUser::where('id', $apiUser['id'])->value('auth');
            $auths = array_unique(array_merge($auths, explode(',', $userAuth)));
            if (!empty($auths)) {
                $whereIn = ['id', $auths];
            } else {
                $where[] = ['id', '=', 0, 'AND'];
            }
        }

        if (!$tag) {
            $btnQuery = WfMenu::where($where);
            if ($whereIn) {
                $btnQuery->whereIn($whereIn[0], $whereIn[1]);
            }

            return $btnQuery->pluck('authtype');
        }

        $query = WfMenu::where($where);
        if ($whereIn) {
            $query->whereIn($whereIn[0], $whereIn[1]);
        }

        $query->orderBy('order_num', 'asc')->orderBy('id', 'asc');
	    $menu = $query->get()->toArray();

        // 处理流程节点外挂信息
        $WORKFLOW = static::dealMenuOfWorkFlow($apiUser);
        $menu = array_merge($menu, $WORKFLOW);
        // 处理客户列表流程外挂信息
        $CUSTMORS = static::dealMenuOfCustmorList($apiUser);
        $menu = array_merge($menu, $CUSTMORS);
        // 处理历史记录流程外挂信息
        $HISTORY = static::dealMenuOfHistory($apiUser);
        $menu = array_merge($menu, $HISTORY);

        foreach ($menu as $k => $v) {
            $menu[$k]['id'] = (string)$v['id'];
            $menu[$k]['parent_id'] = (string)$v['parent_id'];
        }
        
        return static::arrayToTree($menu);
	}

    public static function dealMenuOfHistory($apiUser)
    {
        $HSID = (array)WfMenu::where('tag', 'HISTORY')->value('id');
        if (empty($HSID)) {
            return [];
        }

        $jsonData = [];
        $tools = Tools::getInstance();
        $res = $tools->getWorkFlowByBelong($apiUser['company_id'], 1);
        if ($res['error']) {
            return [];
        }

        $workflow = $res['data'];
        foreach ($workflow as $key => $val) {
            $val = (array)$val;
            // 校验是否开启历史记录
            if (!$tools->checkWorkFlowEnableHistoryRecord($val['wf01001'])) continue;

            $flowId =  (string)'H' . $val['id'];
            $jsonData[] = [
                'id' => (string)$flowId,
                'title' => 'H-' . $val['wf01002'],
                'parent_id' => (string)$HSID[0],
                'status' => 1,
                'order_num' => $key,
                'show' => '',
                'path' => 'history/' . $val['wf01001'],
                'component' => 'views/workbench/workhome/history',
                'icon' => '',
                'type' => 'menu',
                'remark' => '',
                'authtype' => '',
                'tag' => '',
                'created_at' => $val['created_at'],
                'updated_at' => $val['updated_at'],
                'flowId' => $val['wf01001']
            ];
        }

        return $jsonData;
    }

    public static function dealMenuOfCustmorList($apiUser)
    {
        $CSID = (array)WfMenu::where('tag', 'CUSTMOR')->value('id');
        if (empty($CSID)) {
            return [];
        }
        $jsonData = [];
        $tools = Tools::getInstance();
        $res = $tools->getWorkFlowByBelong($apiUser['company_id'], 1);
        if ($res['error']) {
            return [];
        }

        $workflow = $res['data'];
        foreach ($workflow as $key => $val) {
            $val = (array)$val;
            $flowId =  (string)'C' . $val['id'];
            $jsonData[] = [
                'id' => (string)$flowId,
                'title' => $val['wf01002'],
                'parent_id' => (string)$CSID[0],
                'status' => 1,
                'order_num' => $key,
                'show' => '',
                'path' => 'customer/' . $val['wf01001'],
                'component' => 'views/workbench/workhome/customer',
                'icon' => '',
                'type' => 'menu',
                'remark' => '',
                'authtype' => '',
                'tag' => '',
                'created_at' => $val['created_at'],
                'updated_at' => $val['updated_at'],
                'flowId' => $val['wf01001']
            ];
        }

        return $jsonData;
    }

    public static function dealMenuOfWorkFlow($apiUser)
    {
        $WFID = (array)WfMenu::where('tag', 'WORKFLOW')->value('id');
        if (empty($WFID)) {
            return [];
        }
        $tools = Tools::getInstance();
        $res = $tools->getWorkFlowByBelong($apiUser['company_id'], 1);

        if ($res['error']) {
            return [];
        }

        $getWorkNodes = function ($flowId, $parentId) use ($tools) {
            $res = $tools->getWorkNodeByFlowId($flowId);
            if ($res['error']) return false;
            $nodes = $res['data'];
            foreach ($nodes as $key => $val) {
                $val = (array)$val;
                yield [
                    'id' => 'N' . $val['id'],
                    'title' => $val['wf02003'],
                    'parent_id' => $parentId,
                    'status' => 1,
                    'order_num' => $val['wf02009'],
                    'show' => '',
                    'path' => 'worktodo/' . $val['wf02001'] . '/' . $val['wf02002'],
                    'component' => 'views/workbench/workhome/worktodo',
                    'icon' => '',
                    'type' => 'menu',
                    'remark' => '',
                    'authtype' => '',
                    'tag' => '',
                    'created_at' => $val['created_at'],
                    'updated_at' => $val['updated_at'],
                    'flowId' => $val['wf02001'],
                    'nodeId' => $val['wf02002'],
                ];
            }
        };

        $jsonData = [];
        $workflow = $res['data'];
        foreach ($workflow as $key => $val) {
            $val = (array)$val;
            $flowId =  (string)- $val['id'];
            $jsonData[] = [
                'id' => (string)$flowId,
                'title' => $val['wf01002'],
                'parent_id' => (string)$WFID[0],
                'status' => 1,
                'order_num' => $key,
                'show' => '',
                'path' => '/workhome',
                'component' => '',
                'icon' => 'iconfont df-iconshitu',
                'type' => 'menu',
                'remark' => '',
                'authtype' => '',
                'tag' => '',
                'created_at' => $val['created_at'],
                'updated_at' => $val['updated_at'],
                'flowId' => $val['wf01001']
            ];

            $nodeJson = $getWorkNodes($val['wf01001'], $flowId);
            if ($nodeJson === false) continue;
            $jsonData = array_merge($jsonData, iterator_to_array($nodeJson));
        }

        return $jsonData;
    }

    public static function arrayToTree($list, $pk = 'id', $pid = 'parent_id', $child = 'sub', $root = 0)
    {
        // 创建Tree
        $tree = array();
        if (is_array($list)) {
            // 创建基于主键的数组引用
            $refer = array();
            foreach ($list as $key => $data) {
                $list[$key][$child] = [];
                $refer[$data[$pk]] =& $list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $data = \is_object($data) ? (array)$data : $data;
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[] =& $list[$key];
                } else {
                    if (isset($refer[$parentId])) {
                        $parent =& $refer[$parentId];
                        $parent[$child][] =& $list[$key];
                    }
                }
            }
        }
        return $tree;
    }

    // 图片文件上传
    public function fileUploadStore(Request $request)
    {
        $file = null;
        $tag = null;
        if ($request->hasFile('file')) {
            $file = $request->file('file');
        } elseif ($request->hasFile('images')) {
            $file = $request->file('images');
        } elseif ($request->hasFile('editormd-image-file')) {
            $file = $request->file('editormd-image-file');
            $tag = 'md';
        } elseif ($request->hasFile('image')) {
            $file = $request->file('image');
        }

        // 不存在上传文件信息
        if (is_null($file)) {
            return $this->jsonReturns(50000, trans('wf.The-Empty-File-Error'));
        }

        // 判断文件是否有效
        if (!$file->isValid()) {
            return $this->jsonReturns(50000, trans('wf.The-Upload-File-Is-Not-Valid'));
        }

        // 文件扩展后缀
        $fileExtension = strtolower($file->getClientOriginalExtension());
        // if (!in_array($fileExtension, Config::get('api.image_suffix'))) {
        //     return $this->jsonReturns(50000, trans('The-File-Suffix-Can-Not-Be-Allowed', ['suffix' => $fileExtension]));
        // }

        $tmpFile = $file->getRealPath();
        // 文件上传处理
        $fileName = 'birts/' . Uuid::uuid1()->getHex() . '.' . $fileExtension;
        // 文件存储
        if (Storage::disk('template')->put($fileName, file_get_contents($tmpFile))) {
            return Response::json(['code' => 10000, 'message' => trans('wf.Upload-Success'), 'data' => [
                'key' => '/template/' . $fileName,
                'src' => get_domain(request()->server()) . '/template/' . $fileName,
            ]]);
        }
    }
}
